#include "procutil.h"


DWORD const getPidFromExe( char const * const exeName ) {
	DWORD pid = NULL;
	PROCESSENTRY32 processEntry;
	HANDLE hSnapshot = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS, NULL );
	processEntry.dwSize = sizeof(processEntry);

	if ( hSnapshot && Process32First( hSnapshot, &processEntry ) ) {
		
		if ( strcmp( exeName, processEntry.szExeFile ) == 0 )
			pid = processEntry.th32ProcessID;


		while ( pid == NULL && Process32Next( hSnapshot, &processEntry ) ) {
			if ( strcmp( exeName, processEntry.szExeFile ) == 0 )
				pid = processEntry.th32ProcessID;
		}
	}

	return pid;
}

DWORD const getPidFromWindowTitle( char const * const title ) {
	HWND hWindow = FindWindow( NULL, title );
	DWORD pid = NULL;

	if ( hWindow ) {
		GetWindowThreadProcessId( hWindow, &pid );
	}

	CloseHandle( hWindow );
	return pid;
}

DWORD const getPid( char const * const name ) {
	DWORD pid = NULL;

	if ( (pid = getPidFromExe( name )) == NULL ) {
		pid = getPidFromWindowTitle( name );
	}

	return pid;
}

BOOL const __fastcall readMemory( HANDLE hProc, DWORD const address, DWORD const length, void * const out ) {
	BOOL success = ReadProcessMemory( hProc, (void*)address, out, length, NULL );
	return success;
}

BOOL const __fastcall writeMemory( HANDLE hProc, DWORD const address, DWORD const length, void * const in ) {
	DEBUG_PRINT( "Writing to memory at address 0x%08X<%X %X %X %X>", address, ((BYTE * const)(in))[0], ((BYTE * const)(in))[1], ((BYTE * const)(in))[2], ((BYTE * const)(in))[3] );
	BOOL success = WriteProcessMemory( hProc, (void*)address, in, length, NULL );
	return success;
}

HANDLE __fastcall makeRemoteSuspendedThread( HANDLE hProc ) {
	HANDLE hThread = CreateRemoteThread(
		hProc,
		NULL,
		1024,
		NULL,
		NULL,
		CREATE_SUSPENDED,
		NULL
		);

	return hThread;
}

void __fastcall resumeAndWait( HANDLE hThread, bool const closeThread ) {
	ResumeThread( hThread );
	WaitForSingleObject( hThread, INFINITE );

	if ( closeThread ) {
		CloseHandle( hThread );
	}
}

HANDLE __fastcall openProcess( DWORD const pid, DWORD desiredAccess ) {
	return OpenProcess( desiredAccess, false, pid );
}